/**
 * Copyright (C) 2018 - 2020 https://github.com/LeeYan9
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.bifrost.service.impl;

import com.bifrost.constant.MerchantConfigurationType;
import com.bifrost.entity.MerchantConfiguration;
import com.bifrost.entity.MerchantConfigurationAlias;
import com.bifrost.entity.MerchantStore;
import com.bifrost.entity.User;
import com.bifrost.model.ConfigurationModel;
import com.bifrost.repository.ConfigurationAliasRepository;
import com.bifrost.repository.MerchantConfigurationRepository;
import com.bifrost.service.MerchantConfigurationService;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.persistence.criteria.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Lee
 * Create Class on 2018/9/6
 * @com.bifrost.service.impl
 * @wechat-mall
 */
@Service
public class MerchantConfigurationServiceImpl implements MerchantConfigurationService {

    @Autowired
    MerchantConfigurationRepository configurationRepository;
    @Autowired
    ConfigurationAliasRepository aliasRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(List<ConfigurationModel> configurationModels, MerchantStore store, User user) {
        for (ConfigurationModel model : configurationModels) {
            MerchantConfiguration configuration = new MerchantConfiguration();
            BeanUtils.copyProperties(model,configuration);
            configuration.setMerchantStore(store);
            MerchantConfigurationType type = getType(model.getType());
            Assert.notNull(type,"门店配置类型找不到");
            configuration.setMerchantConfigurationType(type);
            configuration.setCreatedTimestamp(new Date());
            configuration.setUpdatedTimestamp(new Date());
            configuration.setUpdatedBy(user.getAdminName());
            configurationRepository.save(configuration);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(List<ConfigurationModel> configurationModels, MerchantStore store, User user) {
        MerchantConfiguration configuration;
        MerchantConfigurationAlias alias = aliasRepository.findFirstByMerchantConfigurationType(getType(configurationModels.get(0).getType()));
        for (ConfigurationModel model : configurationModels) {
            if(model.getId()==null){
                configuration = new MerchantConfiguration();
                configuration.setCreatedTimestamp(new Date());
                configuration.setUpdatedTimestamp(new Date());
                configuration.setUpdatedBy(user.getAdminName());
            }else {
                configuration = configurationRepository.findOne(model.getId());
                Assert.notNull(configuration,"门店下该配置不存在 ID："+model.getId());
            }
            BeanUtils.copyProperties(model,configuration);
            configuration.setMerchantStore(store);
            MerchantConfigurationType type = getType(model.getType());
            Assert.notNull(type,"门店配置类型找不到");
            configuration.setMerchantConfigurationType(type);
            configuration.setConfigurationAlias(alias);
            configurationRepository.save(configuration);
        }
    }

    @Override
    public List<Map> configTypes(MerchantStore merchantStore) {

        List<MerchantConfigurationAlias> aliases = aliasRepository.findAllByVisibleIsTrue();
        Assert.notEmpty(aliases,"请先联系管理员，配置门店参数类型");

        ArrayList<Map> list = Lists.newArrayList();
        aliases.forEach(alias -> {
            HashMap<String, Object> map = new HashMap<>();
            map.put("type", alias.getMerchantConfigurationType());
            map.put("typeAlias", alias == null ? "" : alias.getTypeAlias());
            map.put("keyAlias", alias == null ? "" : alias.getKeyAlias());
            map.put("valueAlias", alias == null ? "" : alias.getValueAlias());
            list.add(map);
        });

        /*List<MerchantConfiguration> configurations = configurationRepository.findTypeByMerchantStore(merchantStore.getMerchantId());
        Assert.notEmpty(configurations,"请先联系管理员，配置门店参数类型");
        ArrayList<Map> list = Lists.newArrayList();
        configurations.stream().collect(Collectors.groupingBy(MerchantConfiguration::getConfigurationAlias)).forEach((alias, merchantConfigurations) -> {
            HashMap<String, Object> map = new HashMap<>();
            map.put("type", merchantConfigurations.get(0).getMerchantConfigurationType());
            map.put("typeAlias", alias == null ? "" : alias.getTypeAlias());
            map.put("keyAlias", alias == null ? "" : alias.getKeyAlias());
            map.put("valueAlias", alias == null ? "" : alias.getValueAlias());
            list.add(map);
        });*/
        return list;
    }

    @Override
    public MerchantConfigurationType getType(String type) {
        for (MerchantConfigurationType configurationType : MerchantConfigurationType.values()) {
            if(configurationType.name().equalsIgnoreCase(type)){
                return configurationType;
            }
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void configDelete(Long id) {
        configurationRepository.delete(id);
    }
}
